#include <iostream>
#include <semaphore.h>
#include <fcntl.h> // For O_* constants
#include <sys/stat.h> // For mode constants
#include <unistd.h> // For sleep
#include <sys/types.h>
#include <sys/wait.h>

class ProcessLock {
public:
    ProcessLock(const char* name) {
        // 创建或打开信号量
        sem = sem_open(name, O_CREAT, 0644, 1);
        if (sem == SEM_FAILED) {
            perror("sem_open");
            exit(1);
        }
    }

    ~ProcessLock() {
        sem_close(sem);
        // Uncomment to remove the semaphore
        // sem_unlink(name);
    }

    void lock() {
        sem_wait(sem);
    }

    void unlock() {
        sem_post(sem);
    }

private:
    sem_t* sem;
};

void critical_section(int id) {
    std::cout << "Process " << id << " entering critical section." << std::endl;
    sleep(1); // Simulate work
    std::cout << "Process " << id << " leaving critical section." << std::endl;
}

int main() {
    const char* sem_name = "/my_semaphore"; // Semaphore name
    ProcessLock lock(sem_name);
    
    const int num_processes = 5;
    pid_t pids[num_processes];

    for (int i = 0; i < num_processes; ++i) {
        pids[i] = fork();
        if (pids[i] == 0) { // Child process
            for (int j = 0; j < 3; ++j) { // Each child will enter critical section 3 times
                //lock.lock();
                critical_section(i);
                //lock.unlock();
            }
            return 0; // End child process
        }
    }

    // Parent process waits for all child processes to finish
    for (int i = 0; i < num_processes; ++i) {
        waitpid(pids[i], nullptr, 0);
    }

    // Clean up
    sem_unlink(sem_name);

    return 0;
}
